package com.gosophia.commons.web.action;

import org.apache.struts2.ServletActionContext;
import org.springframework.security.Authentication;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.anonymous.AnonymousAuthenticationToken;

import com.gosophia.commons.exception.BusinessException;
import com.gosophia.commons.exception.CommonException;
import com.gosophia.commons.exception.ConcurrencyException;
import com.gosophia.commons.web.bean.RequestResult;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

/**
 * 
 * 功能： Action通用性属性存放处
 * 
 * @author renxuehui
 * @since 2010-11-10 Copyright (c) 2010 Gosophia corporation All Rights Reserved
 */
public abstract class BaseSupportAction extends ActionSupport {

	/**
	 * 
	 */
	private static final long serialVersionUID = -504370604269179919L;

	@Override
	public final String execute() throws Exception {
		String result = SUCCESS;

		// Ajax调用
		if ("XMLHttpRequest".equals(ServletActionContext.getRequest()
				.getHeader("X-Requested-With"))) {
			Authentication auth = SecurityContextHolder.getContext()
					.getAuthentication();
			if (auth == null || auth instanceof AnonymousAuthenticationToken
					|| !(auth.isAuthenticated())) {
				getRequestResult().setRsltCode("AUTH_REQUIRED");
				return SUCCESS;
			}

			try {
				result = _execute();
				if (this.getRequestResult() != null
						&& this.getRequestResult().getRsltCode() != null
						&& !this.getRequestResult().getRsltCode().equals("0")) {
					
					String errorCode = this.getRequestResult().getRsltCode();
					String errorMsg = getText(errorCode);
					if (!errorMsg.equals(errorCode)) {
						this.getRequestResult().setMessage(errorMsg);
					}

				}

			} catch (CommonException e) {
				String errorCode = e.getFaultInfo().getErrorCode();
				String errorMsg = getText(errorCode);
				if (!errorMsg.equals(errorCode)) {
					getRequestResult().setRsltCode(errorCode);
					getRequestResult().setMessage(errorMsg);
					ActionContext.getContext().getSession().put(
							"_lastOpResult", getRequestResult());
				}
				result = SUCCESS;
			} catch (BusinessException e) {
				String errorCode = e.getFaultInfo().getErrorCode();
				String errorMsg = getText(errorCode);
				if (!errorMsg.equals(errorCode)) {
					getRequestResult().setRsltCode(errorCode);
					getRequestResult().setMessage(errorMsg);
					ActionContext.getContext().getSession().put(
							"_lastOpResult", getRequestResult());
				}
				result = SUCCESS;
			}
		} else {
			try {
				result = _execute();
				RequestResult requestResult = (RequestResult) ActionContext
						.getContext().getSession().get("_lastOpResult");
				if (requestResult != null
						&& !requestResult.getRsltCode().equals("0")) {
					String errorCode = ((RequestResult) ActionContext
							.getContext().getSession().get("_lastOpResult"))
							.getRsltCode();
					String errorMsg = getText(errorCode);
					if (!errorMsg.equals(errorCode)) {
						ActionContext.getContext().getSession().remove(
								"_lastOpResult");
						getRequestResult().setRsltCode(errorCode);
						getRequestResult().setMessage(errorMsg);
						ActionContext.getContext().getSession().put(
								"_lastOpResult", getRequestResult());
					}
				}
				
			} catch (BusinessException e) {
				String errorCode = e.getFaultInfo().getErrorCode();
    			if (!getText(errorCode).equals(errorCode )) {
    				    String[] objParams =  e.getFaultInfo().getValues();
	    				getRequestResult().setRsltCode(errorCode);
	    				String message = this.getText(errorCode, objParams);
	    				throw new BusinessException(message, errorCode,objParams);
    			}else{
	    				String message = e.getFaultInfo().getMessage();
	    				throw new BusinessException(message, errorCode);
    			}
			} catch (ConcurrencyException e) {
				String errorCode = e.getFaultInfo().getErrorCode();
    			if(!getText(errorCode).equals(errorCode )){
    				String[] objParams =  e.getFaultInfo().getValues();
    				getRequestResult().setRsltCode(errorCode);
    				String message = this.getText(errorCode, objParams);
    				throw new ConcurrencyException(message, errorCode,objParams);
    			}else{
    				String message = e.getFaultInfo().getMessage();
    				throw new ConcurrencyException(message, errorCode);
    			}
			} catch (CommonException e) {
				String errorCode = e.getFaultInfo().getErrorCode();
    			if(!getText(errorCode).equals(errorCode )){
    				String[] objParams =  e.getFaultInfo().getValues();
    				getRequestResult().setRsltCode(errorCode);
    				String message = this.getText(errorCode, objParams);
    				throw new CommonException(message, errorCode,objParams);
    			}else{
    				String message = e.getFaultInfo().getMessage();
    				throw new CommonException(message, errorCode);
    			}
			}
		}

		return result;
	}

	public abstract String _execute() throws Exception;

	/**
	 * 页面选择的菜单Id
	 */
	private String selectedMenuId;

	public String getSelectedMenuId() {
		return selectedMenuId;
	}

	public void setSelectedMenuId(String selectedMenuId) {
		this.selectedMenuId = selectedMenuId;
	}

	/**
	 * 页面ajax或表单提交后，给页面提供的返回结果类
	 */
	private RequestResult requestResult = new RequestResult();

	public RequestResult getRequestResult() {
		// Ajax调用
		if ("XMLHttpRequest".equals(ServletActionContext.getRequest()
				.getHeader("X-Requested-With"))) {
			ActionContext.getContext().getSession().remove("_lastOpResult");
		}
		// 普通调用
		else if (requestResult != null && requestResult.getMessage() != null
				&& !requestResult.getMessage().isEmpty()) {
			ActionContext.getContext().getSession().put("_lastOpResult",
					requestResult);
		}

		return this.requestResult;
	}

	public void setRequestResult(RequestResult requestResult) {
		this.requestResult = requestResult;
	}

	/** 进入任务或者业务页面标识 任务："task"; 业务："business" */
	private String fromFlag;

	public void setFromFlag(String fromFlag) {
		this.fromFlag = fromFlag;
	}

	public String getFromFlag() {
		return fromFlag;
	}
}
